/*/*******************************************
 * 功能说明: ZIP工具类
 * 模块名称: 工具模块
 * 系统名称: 互联网金融平台
 * 软件版权: 北京银杉金服科技有限公司
 * 系统版本: 1.0.0
 * 开发人员: zhaorq
 * 开发时间: 2017年7月11日 上午10:29:32
 * 审核人员:
 * 相关文档:
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.trade.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ZIP工具类
 * @author zhaorq
 * @version 1.0.0.1
 */
public class ZipUtils {

	private static Logger logger = LoggerFactory.getLogger(ZipUtils.class);
	
	public static void main(String[] args) {
		String srcPath = "D:\\新建文本文档.txt";
		ZipUtils.zip(srcPath);
	}

	public static boolean zip(String srcPath) {
		// 要压缩的文件
		File srcFile = new File(srcPath);
		if (!srcFile.exists()) {
			logger.error("源文件不存在，srcPath=" + srcPath);
			return false;
		}
		if (!srcFile.canRead()) {
			logger.error("源文件不可读，srcPath=" + srcPath);
			return false;
		}
		logger.info("源文件大小=" + srcFile.length());
		String zipPath = null;
		if (srcFile.isDirectory()) {// 是目录
			zipPath = srcPath + ".zip";
		} else {
			zipPath = srcPath.substring(0, srcPath.lastIndexOf('.')) + ".zip";
		}
		logger.info("压缩文件路径=" + zipPath);
		// 压缩后的文件
		File zipFile = new File(zipPath);

		ZipOutputStream zos = null;
		boolean result = false;// 是否压缩成功
		try {
			CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(zipFile), new CRC32());
			zos = new ZipOutputStream(cos);
			zip(srcFile, zos, "", true);
			result = true;
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (zos != null)
					zos.close();
			} catch (IOException e) {
				throw new RuntimeException("关闭Zip输出流出现异常", e);
			} finally {
				// 压缩不成功,清理操作
				if (!result && zipFile.exists())
					zipFile.delete();
			}
		}
		return result;
	}

	/**
	 * 压缩zip文件
	 * @param file 压缩的文件对象
	 * @param zos ZIP输出流
	 * @param dir 相对父目录名称
	 * @param boo 是否把空目录压缩进去
	 */
	public static void zip(File file, ZipOutputStream zos, String dir, boolean boo) throws IOException {
		if (file.isDirectory()) {// 是目录
			File[] listFile = file.listFiles();// 得出目录下所有的文件对象
			if (listFile.length == 0 && boo) {// 空目录压缩
				zos.putNextEntry(new ZipEntry(dir + file.getName() + "/"));// 将实体放入输出ZIP流中
				return;
			} else {
				for (File cfile : listFile) {
					zip(cfile, zos, dir + file.getName() + "/", boo);// 递归压缩
				}
			}
		} else if (file.isFile()) {// 是文件
			byte[] bt = new byte[2048 * 2];
			logger.info(file.getName());
			ZipEntry ze = new ZipEntry(dir + file.getName());// 构建压缩实体
			// 设置压缩前的文件大小
			ze.setSize(file.length());
			// 将实体放入输出ZIP流中
			zos.putNextEntry(ze);
			zos.setEncoding("gbk");
			FileInputStream fis = null;
			try {
				fis = new FileInputStream(file);
				int i = 0;
				while ((i = fis.read(bt)) != -1) {// 循环读出并写入输出Zip流中
					zos.write(bt, 0, i);
				}
				logger.info("文件压缩成功！");
			} catch (IOException e) {
				throw new IOException("写入压缩文件出现异常", e);
			} finally {
				try {
					if (fis != null)
						fis.close();// 关闭输入流
				} catch (IOException ex) {
					throw new IOException("关闭输入流出现异常");
				}

			}
		}
	}

}
